// 属性： 宽度，高度，横坐标，纵坐标，横向速度，纵向速度，对应的dom对象

// 道具类
class Prop extends Rectangle {
  constructor(width = 30, height = 30, left, top, xSpeed, ySpeed, dom) {
    super(width, height, left, top, xSpeed, ySpeed, dom);
  }

  onMove() {
    // 道具移动超出容器则移除
    if (this.left <= -(this.width / 2)) {
      this.dom.remove();
    }
  }
}

class PropPare {
  constructor({ speed, type, game }) {
    this.speed = speed;
    this.type = type;
    this.prop = null;
    this.game = game;
    if (type === "opacity") {
      this.createOpacityProp();
    } else if (type === "sprint") {
      this.createSprintProp();
    } else if (type === "protect") {
      this.createProtectProp();
    }
  }

  createOpacityProp() {
    this.createProp("prop-opacity");
  }

  createProtectProp() {
    this.createProp("prop-protect");
  }

  createSprintProp() {
    this.createProp("prop-sprint");
  }

  createProp(className) {
    const prop = document.createElement("div");
    prop.className = className;
    gameDmo.appendChild(prop);

    let validPosition = false;
    let left, top;

    while (!validPosition) {
      left = 200 + Math.random() * 400;
      top = 100 + Math.random() * 300;
      prop.style.left = left + "px";
      prop.style.top = top + "px";

      validPosition = true;

      // 检查是否与任何管道重叠
      this.game.pipeProducer.pares.forEach((pare) => {
        const { upPaie, downPaie } = pare;
        const upPipeRect = {
          left: upPaie.left,
          right: upPaie.left + upPaie.width,
          bottom: upPaie.top + upPaie.height,
        };
        const downPipeRect = {
          left: downPaie.left,
          right: downPaie.left + downPaie.width,
          top: downPaie.top,
        };
        const propRect = { left, top, width: 30, height: 30 };

        if (
          (propRect.left < upPipeRect.right &&
            propRect.left + propRect.width > upPipeRect.left &&
            propRect.top < upPipeRect.bottom) ||
          (propRect.left < downPipeRect.right &&
            propRect.left + propRect.width > downPipeRect.left &&
            propRect.top + propRect.height > downPipeRect.top)
        ) {
          validPosition = false;
        }
      });
    }

    this.prop = new Prop(30, 30, left, top, this.speed, 0, prop);
  }

  move(duration) {
    this.prop.move(duration);
  }

  /**
   * 判断该道具是否移出了视野
   */
  get uesLess() {
    return this.prop.left < -this.prop.width;
  }
}

/**
 * 批量生成道具
 */
class PropPareProducer {
  /**
   *
   * @param {移动速度} speed
   * @param {道具生成间隔} tick
   */
  constructor(speed, tick = 1800) {
    this.speed = speed;
    this.pares = [];
    this.tick = tick;
    this.start = false;
    this.timer = false;
    this.game = null;
  }

  renderProduce() {
    if (this.game.bard.status != "normal") {
      return;
    }
    let prop = null;
    // 10% 生成道具
    if (Math.random() < 0.7) {
      const rand = Math.random();
      if (rand < 0.18) {
        prop = new PropPare({
          speed: this.speed,
          game: this.game,
          type: "opacity",
        });
      } else if (rand > 0.18 && rand < 1) {
        prop = new PropPare({
          speed: this.speed,
          game: this.game,
          type: "sprint",
        });
      } else if (rand > 0.3 && rand < 0.5) {
        prop = new PropPare({
          speed: this.speed,
          game: this.game,
          type: "protect",
        });
      }
    }

    if (prop) {
      this.pares.push(prop); // 生成道具，并添加到数组
    }

    // 移除用不到的道具
    this.pares.forEach((pare, i) => {
      if (pare.uesLess) {
        this.pares.splice(i, 1);
      }
    });
  }

  render() {
    if (this.timer) {
      clearTimeout(this.timer);
    }
    if (this.start) {
      this.timer = setTimeout(() => {
        this.renderProduce();
        this.render();
      }, this.tick);
    }
  }

  removeProp(dom, index) {
    dom.remove();
    this.pares.splice(index, 1);
  }

  startRender({ tick, game }) {
    this.game = game;
    if (tick) {
      this.tick = tick;
    }
    this.start = true;
    this.render();
  }
  stopProduce() {
    this.start = false;
    clearTimeout(this.timer);
    this.timer = null;
  }
}
